#pragma once

#include <butil/string_printf.h>

#include "hawking/indexlib/index_config.pb.h"
#include "index/inverted_index/inverted_mem_indexer/posting/posting_writer.h"
#include "index/inverted_index/inverted_indexer.h"
#include "util/status.h"
#include "util/pool/pool.h"
#include "util/hashmap/hash_map.h"

namespace hawking {
namespace indexlib {

class InvertedMemIndexer : public InvertedIndexer {
public:
    InvertedMemIndexer() = default;
    virtual ~InvertedMemIndexer() = default;

    Status Init(
        const std::string& field_name,
        const std::unordered_set<uint64_t>& high_freq_termkeys = {});

    Status AddDocument(NormalDocument* doc);

    virtual Status UpdateDocument(
        uint64_t old_term, uint64_t new_term, DocId doc_id) override;

    virtual Status Lookup(
        uint64_t term_key, uint32_t topk, SegmentContext* segment_ctx) override;

    Status Dump(
        const std::string& inverted_dir, 
        const std::unordered_map<DocId, DocId>& old2new_map);

    size_t MemoryUse() const {
        return pool_->UsedBytes();
    }

private:
    void AddTerm_(uint64_t term, DocId doc_id);

    int32_t field_id_;
    size_t hashmap_init_size_ = 4096;

    std::unique_ptr<MMapAllocator> allocator_;
    std::unique_ptr<Pool> pool_;

    std::unique_ptr<HashMap<uint64_t, PostingWriter*>> posting_table_;
};

}
}
